import requests
import sys
import re
import os
import zipfile
import shutil
import execjs
import json
import urllib.parse
from fileUtils import FileHelper
import time
import shelve  

class ComicBookItem():
    FIELDS = ["name", "desc", "tag", "cover_image_url", "author",
              "source_url", "source_name", "crawl_time", "chapters"]

    def __init__(self, name=None, desc=None, tag=None, cover_image_url=None,
                 author=None, source_url=None, source_name=None,
                 crawl_time=None, chapters=None):
        self.name = name or ""
        self.desc = desc or ""
        self.tag = tag or ""
        self.cover_image_url = cover_image_url or ""
        self.author = author or ""
        self.source_url = source_url or ""
        self.source_name = source_name or ""
        self.crawl_time = crawl_time or datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        # [{"chapter_number": 1, "title": "xx"}, ]
        self.chapters = sorted(chapters, key=lambda x: x["chapter_number"]) if chapters else []

    @classmethod
    def create_chapter(cls, chapter_number, title):
        return {"chapter_number": chapter_number, "title": title}

    def create_chapters(cls, param_list):
        return [cls.create_chapter(**param) for param in param_list]

    def to_dict(self):
        return {field: getattr(self, field) for field in self.FIELDS}


class ChapterItem():
    FIELDS = ["chapter_id","chapter_number", "title", "image_urls", "source_url"]

    def __init__(self, chapter_number, title, image_urls, source_url=None):
        self.__init__('',chapter_number, title, image_urls, source_url)
        

    def __init__(self,chapter_id, chapter_number, title, image_urls, source_url=None):
        self.chapter_id = chapter_id or ""
        self.chapter_number = chapter_number
        self.title = title or ""
        self.image_urls = image_urls or []
        self.source_url = source_url or ""

    def to_dict(self):
        return {field: getattr(self, field) for field in self.FIELDS}


class CrawlerBase():
 
    CONNECTTIME = 10
    TIMEOUT = 30
    DEFAULT_HEADERS = {
        'User-Agent': ('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) '
                       'Chrome/65.0.3325.146 Safari/537.36')
    }
    DOWNLOAD_PATH = "./download/"

    SOURCE_NAME = "未知"
    SITE = ""
    HOST = "http://99.hhxxee.com"

    TARGET_HOST = ""
    IMG_HOST = ""
    COMIC_ID=""
    COMIC_NAME=""
    

    _session = None

    DRIVER_PATH = None
    DRIVER_TYPE = None
    DEFAULT_DRIVER_TYPE = "Chrome"
    SUPPORT_DRIVER_TYPE = frozenset(["Firefox", "Chrome", "Opera", "Ie"])

    loadImgErrorCount = 0
    loadImgErrorCountSum=0
    connectErroCount = 0

    keyIsLoadedChapters = ''
    keyChapters = ''

    def __init__(self,site,host,target_host,img_host,comic_name,commic_id):
        self.SITE = site
        self.HOST = host
        self.TARGET_HOST = target_host
        self.IMG_HOST = img_host
        self.COMIC_NAME = comic_name 
        self.COMIC_ID = commic_id 

        self.keyIsLoadedChapters = self.SITE+'_'+self.COMIC_ID+'_isLoadedChapters'
        self.keyChapters = self.SITE+'_'+self.COMIC_ID+'_chapters'

        self.dbase = shelve.open('commic_dbase')
        self._session = requests.session()
        self.chapterList = []
         
    def log(self,content):
        filePath = self.DOWNLOAD_PATH + self.COMIC_NAME+"/"
        if not os.path.exists(filePath):
                    os.makedirs(filePath)
        f=open(filePath+'log.txt','a+')
        f.write(str(content)+'\n')
        f.close()

    def load_img_wait(self,url,filePath,imageName):
            self.loadImgErrorCountSum = self.loadImgErrorCountSum+1
            self.loadImgErrorCount = self.loadImgErrorCount+1
            if self.loadImgErrorCountSum>10:
                print("下载图片失败")
                self.log("下载失败:"+url+"\n")
                sys.exit()
                return
            if self.loadImgErrorCount<2 :
                time.sleep(2)
                self.load_image(url,filePath,imageName)

    # 下载单个图片并保存
    def load_image(self,url,filePath,imageName):
        try:
            targetPic = self.get_html(url)
            FileHelper.save_file(filePath,imageName,targetPic.content)
        
        except Exception as e:
            msg = "图片URL链接访问异常！ url={}".format(url + " path="+filePath+imageName+"\n"+e.__str__())
            print(msg)
            self.load_img_wait(url,filePath,imageName)
        else:
            self.loadImgErrorCountSum = 0
            print("下载图片完成："+imageName)


    def load_chapter(self,chapter):
        index = 1
        filePath = self.DOWNLOAD_PATH + self.COMIC_NAME+"/"+chapter.title+"("+str(len(chapter.image_urls))+"p)/"
        print("开始下载章节"+str(index)+"："+filePath)
        for imgs in chapter.image_urls:
            if not self.filterImgs(filePath+str(index)+".jpg"):
                print('正在下载'+str(index)+":"+imgs)
                self.loadImgCount=0
                self.load_image(imgs,filePath,str(index)+".jpg")
            index = index+1   
       

    def load_chapters(self):
        for chapter in self.chapterList:
            if self.filterChapters(chapter.title,chapter.chapter_number):
                self.load_chapter(chapter)

    # 过滤章节   
    def filterChapters(self,chapterName,chapterIndex):
        # if chapterIndex<15:
        #     return False
        return True

   
    # 过滤章节图片   
    def filterImgs(self,filePath):
        if not os.path.exists(filePath):
            return False
        return True

    def get_comic_info_error(self):
        self.connectErroCount = self.connectErroCount+1
        if self.connectErroCount<10:
                time.sleep(2)
                self.get_comic_info()

    def get_comicbook_item(self):
        """
        :return :
        """
        raise NotImplementedError

    def get_comic_info(self):
        """
        :return :
        """
        raise NotImplementedError


    def get_html(self, url):
        response = self._session.get(url, headers=self.DEFAULT_HEADERS,timeout=(self.CONNECTTIME,self.TIMEOUT))
        return response
  
    def run(self):
        # self.dbase.clear()
        self.get_comic_info()
